package thread;

import network.Network;
import network.Rule;
import util.Logger;

import java.util.ArrayList;

public class LibraInstance {
    private static int cnt = 0;

    private Network n;
    private int uid, prefix;
    private long dstIp;
    private double changeCnt, ruleCnt;
    private Logger logger;

    public static ArrayList<LibraInstance> divideByHeaders(Network network, int prefix) {
        ArrayList<LibraInstance> ret = new ArrayList<>();

        for (long i = 0; i < (1 << prefix); i ++) {
            LibraInstance ins = new LibraInstance(network.clone(), i << (32 - prefix), prefix);
            ins.getNetwork().initializeModelAndRules(ins.dstIp, ins.prefix);
            ret.add(ins);
        }

        return ret;
    }

    public LibraInstance(Network network, long dstIp, int prefix) {
        this.n = network;
        this.changeCnt = 0;
        this.uid = cnt ++;
        this.logger = new Logger();
        this.dstIp = dstIp;
        this.prefix = prefix;
    }

    public boolean relatedTo(Rule rule) {
        int t = Math.min(this.prefix, rule.getPriority());
        return (this.dstIp >> (32 - t)) == (rule.getDstIp() >> (32 - t));
    }

    public long getDstIp() {
        return this.dstIp;
    }

    public int getPrefix() {
        return this.prefix;
    }
    public int getUid() {
        return this.uid;
    }

    public Logger getLogger() {
        return this.logger;
    }

    public void ruleCnt(int delta) {
        this.ruleCnt += delta;
    }

    public void changeCnt(int delta) {
        this.changeCnt += delta;
    }

    public double getRuleCnt() {
        return this.ruleCnt;
    }

    public double getChangeCnt() {
        return this.changeCnt;
    }

    public Network getNetwork() {
        return this.n;
    }
}
